home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / perl5 / Any / Moose.pm
Encoding:
Perl POD Document  |  2010-05-18  |  7.9 KB  |  351 lines

  1. package Any::Moose;
  2. BEGIN {
  3.   $Any::Moose::VERSION = '0.13';
  4. }
  5. # ABSTRACT: use Moose or Mouse modules
  6.  
  7. use 5.006_002;
  8. use strict;
  9. use warnings;
  10.  
  11. # decide which backend to use
  12. our $PREFERRED;
  13. do {
  14.     local $@;
  15.     if ($ENV{ANY_MOOSE}) {
  16.         $PREFERRED = $ENV{'ANY_MOOSE'};
  17.         warn "ANY_MOOSE is not set to Moose or Mouse"
  18.             unless $PREFERRED eq 'Moose'
  19.                 || $PREFERRED eq 'Mouse';
  20.  
  21.         # if we die here, then perl gives "unknown error" which doesn't tell
  22.         # you what the problem is at all. argh.
  23.         if ($PREFERRED eq 'Moose' && !eval { require Moose }) {
  24.             warn "\$ANY_MOOSE is set to Moose but we cannot load it";
  25.         }
  26.         elsif ($PREFERRED eq 'Mouse' && !eval { require Mouse }) {
  27.             warn "\$ANY_MOOSE is set to Mouse but we cannot load it";
  28.         }
  29.     }
  30.     elsif (_is_moose_loaded()) {
  31.         $PREFERRED = 'Moose';
  32.     }
  33.     elsif (eval { require Mouse }) {
  34.         $PREFERRED = 'Mouse';
  35.     }
  36.     elsif (eval { require Moose }) {
  37.         $PREFERRED = 'Moose';
  38.     }
  39.     else {
  40.         require Carp;
  41.         warn "Unable to locate Mouse or Moose in INC";
  42.     }
  43. };
  44.  
  45. sub import {
  46.     my $self = shift;
  47.     my $pkg  = caller;
  48.  
  49.     # Any::Moose gives you strict and warnings
  50.     strict->import;
  51.     warnings->import;
  52.  
  53.     # first options are for Mo*se
  54.     unshift @_, 'Moose' if !@_ || ref($_[0]);
  55.  
  56.     while (my $module = shift) {
  57.         my $options = @_ && ref($_[0]) ? shift : [];
  58.  
  59.         $options = $self->_canonicalize_options(
  60.             module  => $module,
  61.             options => $options,
  62.             package => $pkg,
  63.         );
  64.  
  65.         $self->_install_module($options);
  66.     }
  67.  
  68.     # give them any_moose too
  69.     no strict 'refs';
  70.     *{$pkg.'::any_moose'} = \&any_moose;
  71. }
  72.  
  73. sub unimport {
  74.     my $sel = shift;
  75.     my $pkg = caller;
  76.     my $module;
  77.  
  78.     if(@_){
  79.         $module = any_moose(shift, $pkg);
  80.     }
  81.     else {
  82.         $module = _backer_of($pkg);
  83.     }
  84.     my $e = do{
  85.         local $@;
  86.         eval "package $pkg;\n"
  87.            . '$module->unimport();';
  88.         $@;
  89.    };
  90.  
  91.    if ($e) {
  92.         require Carp;
  93.         Carp::croak("Cannot unimport Any::Moose: $e");
  94.    }
  95.  
  96.    return;
  97. }
  98.  
  99. sub _backer_of {
  100.     my $pkg = shift;
  101.  
  102.     if(exists $INC{'Mouse.pm'}){
  103.         my $meta = Mouse::Util::get_metaclass_by_name($pkg);
  104.         if ($meta) {
  105.             return 'Mouse::Role' if $meta->isa('Mouse::Meta::Role');
  106.             return 'Mouse'       if $meta->isa('Mouse::Meta::Class');
  107.        }
  108.     }
  109.  
  110.     if (_is_moose_loaded()) {
  111.         my $meta = Class::MOP::get_metaclass_by_name($pkg);
  112.         if ($meta) {
  113.             return 'Moose::Role' if $meta->isa('Moose::Meta::Role');
  114.             return 'Moose'       if $meta->isa('Moose::Meta::Class');
  115.         }
  116.     }
  117.  
  118.     return undef;
  119. }
  120.  
  121. sub _canonicalize_options {
  122.     my $self = shift;
  123.     my %args = @_;
  124.  
  125.     my %options;
  126.     if (ref($args{options}) eq 'HASH') {
  127.         %options = %{ $args{options} };
  128.     }
  129.     else {
  130.         %options = (
  131.             imports => $args{options},
  132.         );
  133.     }
  134.  
  135.     $options{package} = $args{package};
  136.     $options{module}  = any_moose($args{module}, $args{package});
  137.  
  138.     return \%options;
  139. }
  140.  
  141. sub _install_module {
  142.     my $self    = shift;
  143.     my $options = shift;
  144.  
  145.     my $module = $options->{module};
  146.     (my $file = $module . '.pm') =~ s{::}{/}g;
  147.  
  148.     require $file;
  149.  
  150.     my $e = do {
  151.         local $@;
  152.         eval "package $options->{package};\n"
  153.            . '$module->import(@{ $options->{imports} });';
  154.         $@;
  155.     };
  156.     if ($e) {
  157.         require Carp;
  158.         Carp::croak("Cannot import Any::Moose: $e");
  159.     }
  160.     return;
  161. }
  162.  
  163. sub any_moose {
  164.     my $fragment = _canonicalize_fragment(shift);
  165.     my $package  = shift || caller;
  166.  
  167.     # Mouse gets first dibs because it doesn't introspect existing classes
  168.  
  169.     my $backer = _backer_of($package) || '';
  170.  
  171.     if ($backer =~ /^Mouse/) {
  172.         $fragment =~ s/^Moose/Mouse/;
  173.         return $fragment;
  174.     }
  175.  
  176.     return $fragment if $backer =~ /^Moose/;
  177.  
  178.     $fragment =~ s/^Moose/Mouse/ if mouse_is_preferred();
  179.     return $fragment;
  180. }
  181.  
  182. for my $name (qw/
  183.     load_class
  184.     is_class_loaded
  185.     class_of
  186.     get_metaclass_by_name
  187.     get_all_metaclass_instances
  188.     get_all_metaclass_names
  189.     load_first_existing_class
  190.         /) {
  191.     no strict 'refs';
  192.     *{__PACKAGE__."::$name"} = moose_is_preferred()
  193.         ? *{"Class::MOP::$name"}
  194.         : *{"Mouse::Util::$name"};
  195. }
  196.  
  197. sub moose_is_preferred { $PREFERRED eq 'Moose' }
  198. sub mouse_is_preferred { $PREFERRED eq 'Mouse' }
  199.  
  200. sub _is_moose_loaded { exists $INC{'Moose.pm'} }
  201.  
  202. sub is_moose_loaded {
  203.     require Carp;
  204.     Carp::carp("Any::Moose::is_moose_loaded is deprecated. Please use Any::Moose::moose_is_preferred instead");
  205.     goto \&_is_moose_loaded;
  206. }
  207.  
  208. sub _canonicalize_fragment {
  209.     my $fragment = shift;
  210.  
  211.     return 'Moose' if !$fragment;
  212.  
  213.     # any_moose("X::Types") -> any_moose("MooseX::Types")
  214.     $fragment =~ s/^X::/MooseX::/;
  215.  
  216.     # any_moose("::Util") -> any_moose("Moose::Util")
  217.     $fragment =~ s/^::/Moose::/;
  218.  
  219.     # any_moose("Mouse::Util") -> any_moose("Moose::Util")
  220.     $fragment =~ s/^Mouse(X?)\b/Moose$1/;
  221.  
  222.     # any_moose("Util") -> any_moose("Moose::Util")
  223.     $fragment =~ s/^(?!Moose)/Moose::/;
  224.  
  225.     return $fragment;
  226. }
  227.  
  228. 1;
  229.  
  230.  
  231. =pod
  232.  
  233. =head1 NAME
  234.  
  235. Any::Moose - use Moose or Mouse modules
  236.  
  237. =head1 VERSION
  238.  
  239. version 0.13
  240.  
  241. =head1 SYNOPSIS
  242.  
  243.  
  244. =head2 BASIC
  245.  
  246.  
  247.     package Class;
  248.  
  249.     # uses Moose if it's loaded or demanded, Mouse otherwise
  250.     use Any::Moose;
  251.  
  252.     # cleans the namespace up
  253.     no Any::Moose;
  254.  
  255. =head2 OTHER MODULES
  256.  
  257.  
  258.     package Other::Class;
  259.     use Any::Moose;
  260.  
  261.     # uses Moose::Util::TypeConstraints if the class has loaded Moose,
  262.     # Mouse::Util::TypeConstraints otherwise.
  263.     use Any::Moose '::Util::TypeConstraints';
  264.  
  265. =head2 ROLES
  266.  
  267.  
  268.     package My::Sorter;
  269.     use Any::Moose 'Role';
  270.  
  271.     requires 'cmp';
  272.  
  273. =head2 COMPLEX USAGE
  274.  
  275.  
  276.     package My::Meta::Class;
  277.     use Any::Moose;
  278.  
  279.     # uses subtype from Moose::Util::TypeConstraints if the class loaded Moose,
  280.     # subtype from Mouse::Util::TypeConstraints otherwise.
  281.     # similarly for Mo*se::Util's does_role
  282.     use Any::Moose (
  283.         '::Util::TypeConstraints' => ['subtype'],
  284.         '::Util' => ['does_role'],
  285.     );
  286.  
  287.     # uses MouseX::Types or MooseX::Types
  288.     use Any::Moose 'X::Types';
  289.  
  290.     # gives you the right class name depending on which Mo*se was loaded
  291.     extends any_moose('::Meta::Class');
  292.  
  293. =head1 DESCRIPTION
  294.  
  295.  
  296. Though we recommend that people generally use L<Moose>, we accept that Moose
  297. cannot yet be used for everything everywhere. People generally like the Moose
  298. sugar, so many people use L<Mouse>, a lightweight replacement for parts of
  299. Moose.
  300.  
  301.  
  302. Because Mouse strives for compatibility with Moose, it's easy to substitute one
  303. for the other. This module facilitates that substitution. By default, Mouse
  304. will be provided to libraries, unless Moose is already loaded -or-
  305. explicitly requested by the end-user. The end-user can force the decision
  306. of which backend to use by setting the environment variable C<ANY_MOOSE> to
  307. be C<Moose> or C<Mouse>.
  308.  
  309.  
  310. Note that the decision of which backend to use is made only once, so that if
  311. Any-Moose picks Mouse, then a third-party library loads Moose, anything else
  312. that uses Any-Moose will continue to pick Mouse.
  313.  
  314.  
  315. So, if you have to use L<Mouse>, please be considerate to the Moose fanboys
  316. (like myself!) and use L<Any-Moose> instead. C<:)>
  317.  
  318. =head1 SEE ALSO
  319.  
  320.  
  321. L<Moose>
  322.  
  323.  
  324. L<Mouse>
  325.  
  326.  
  327. L<Squirrel> - a deprecated first-stab at Any-Moose-like logic. Its biggest
  328. fault was in making the decision of which backend to use every time it was
  329. used, rather than just once.
  330.  
  331. =head1 AUTHORS
  332.  
  333.   Shawn M Moore <sartak@bestpractical.com>
  334.   Florian Ragwitz <rafl@debian.org>
  335.   Stevan Little <stevan@iinteractive.com>
  336.   Tokuhiro Matsuno <tokuhirom@gmail.com>
  337.   Goro Fuji <gfuji@cpan.org>
  338.  
  339. =head1 COPYRIGHT AND LICENSE
  340.  
  341. This software is copyright (c) 2010 by Best Practical Solutions.
  342.  
  343. This is free software; you can redistribute it and/or modify it under
  344. the same terms as the Perl 5 programming language system itself.
  345.  
  346. =cut
  347.  
  348.  
  349. __END__
  350.  
  351.